﻿/*
 * tcpbindclientdevice.cpp
 *
 *  Created on: 2017年2月21日
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_OS_COM DM_API_EXPORT

#include <dm/os/com/tcpbindclientdevice.hpp>
#include <dm/os/log/logger.hpp>

namespace dm{
namespace os{
namespace com{

static const char* logModule = "CTcpBindClientDevice.com.os.dm";

CTcpBindClientDevice::CTcpBindClientDevice( ios_t& ios,const size_t& rxBufSize ):
		CDevice(rxBufSize),m_dev(ios){
	log().debug( THISMODULE "创建对象");
}

CTcpBindClientDevice::~CTcpBindClientDevice(){
	log().debug( THISMODULE "销毁对象");
	m_dev.shutdown(m_dev.shutdown_both);
	m_dev.close();
}

bool CTcpBindClientDevice::checkAndSetAddress( const CTcpBindClientAddr& addr ){
	m_addr = addr;
	return true;
}

bool CTcpBindClientDevice::startConnect(){
	const CTcpBindClientAddr* addr = m_addr.asTcpBindClient();
	if( !addr ){
		log().warnning(THISMODULE "没有可用的地址信息");
		return false;
	}

	try{
		m_dev.open(boost::asio::ip::tcp::v4());
		m_dev.set_option(boost::asio::ip::tcp::socket::reuse_address(true));
		end_t local(ip_t::from_string(addr->getLocalHost()),addr->getLocalPort());
		m_dev.bind(local);

		m_dev.async_connect(end_t(ip_t::from_string(addr->getServerHost().c_str()),addr->getServerPort()),
				boost::bind(&CTcpBindClientDevice::handler_connect,this,boost::asio::placeholders::error));
	}catch( std::exception& ec ){
		log().error(THISMODULE "打开设备%s失败(%s)",m_addr.toString().c_str(),ec.what());
		return false;
	}

	return true;
}

bool CTcpBindClientDevice::stopConnect(){
	try{
		m_dev.close();
		error_t ec;
		handler_disconnect(ec);
	}catch( std::exception& e ){
		log().warnning(THISMODULE "关闭设备异常%s",e.what());
		return false;
	}

	return true;
}

bool CTcpBindClientDevice::startSend( const dm::uint8* buf,const size_t& len ){
	try{
		boost::asio::async_write( m_dev,boost::asio::buffer(buf,len),
				boost::bind(&CTcpBindClientDevice::handler_tx,this,
						boost::asio::placeholders::error)
		);
	}catch( std::exception& e ){
		log().warnning(THISMODULE "send %d bytes fail(%s)",len,e.what());
		return false;
	}

	return true;
}

void CTcpBindClientDevice::start_rx(){
	try{
		m_dev.async_receive(boost::asio::buffer(m_rxBuf.get(),m_rxBufSize),
				boost::bind(&CTcpBindClientDevice::handler_rx,this,
						boost::asio::placeholders::error,
						boost::asio::placeholders::bytes_transferred)
		);
	}catch( std::exception& ec ){
		log().error(THISMODULE "开启监听失败%s",ec.what());
	}
}

void CTcpBindClientDevice::cancelDev(){
	try{
		m_dev.cancel();
	}catch( std::exception& ec ){
		log().error(THISMODULE "取消设备失败%s",ec.what());
	}
}

}
}
}


